using System;
using System.Collections.Generic;
using System.Text;

using System.Reflection;
using System.Threading;

using Microsoft.SharePoint;

using System.Web;
using System.Security.Permissions;

namespace WMOSSExperts
{
    public class FieldHelper
    {
        /// <summary>
        /// Set the reverseLookupField attribute. As this method is internal it is called by reflection
        /// </summary>
        /// <param name="attribute">Attribute name</param>
        /// <param name="value">Attribute value</param>
        [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Unrestricted)]
        public static void SetFieldAttribute(string attribute, string value, Object instance)
        {
            MethodInfo method = instance.GetType().GetMethod("SetFieldAttributeValue",
                BindingFlags.Instance | BindingFlags.NonPublic);
            method.Invoke(instance, new object[] { attribute, value });
        }

        /// <summary>
        /// Set the reverseLookupField attribute. As this method is internal it is called by reflection
        /// </summary>
        /// <param name="attribute">Attribute name</param>
        /// <param name="value">Attribute value</param>
        /// 
        [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Unrestricted)]
        public static string GetFieldAttribute(string attribute, Object instance)
        {
            MethodInfo method = instance.GetType().GetMethod("GetFieldAttributeValue",
                BindingFlags.Instance | BindingFlags.NonPublic,
                null,
                new Type[] { typeof(String) },
                null
            );

            object obj = method.Invoke(instance, new object[] { attribute });

            if (obj == null)
                return string.Empty;
            else
                return obj.ToString();
        }

        /// <summary>
        /// Store data in the current thread to manage a property schema reverseLookupField
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        public static void SetNamedThreadData(string propertyName, string value)
        {
            Thread.SetData(Thread.GetNamedDataSlot(propertyName), value);
        }

        public static string GetNamedThreadData(string propertyName)
        {
            return (string)Thread.GetData(Thread.GetNamedDataSlot(propertyName));
        }

        [CLSCompliant(false)]
        public static string GetCurrentPropertyValue(SPField field, string propertyName)
        {
            string namedThreadData = FieldHelper.GetNamedThreadData(propertyName);
            if (string.IsNullOrEmpty(namedThreadData))
            {
                namedThreadData = (string)field.GetCustomProperty(propertyName);
            }
            return namedThreadData;
        }

        /// <summary>
        /// Gets a reverseLookupField in a sourceList
        /// </summary>
        /// <param name="targetedList"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        [CLSCompliant(false)]
        public static SPField GetExistingField(SPList list, String columnName)
        {
            if (list.Fields.ContainsField(columnName))
            {
                return list.Fields[columnName];
            }
            return null;
        }


        /// <summary>
        /// Gets a reverseLookupField in a sourceList
        /// </summary>
        /// <param name="targetedList"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        [CLSCompliant(false)]
        public static SPField GetExistingField(SPList list, Guid fieldId)
        {
            try
            {
                return list.Fields[fieldId];
            }
            catch
            {
                return null;
            }
        }
    }
}
